from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Query
from fastapi.responses import FileResponse
from sqlalchemy.ext.asyncio import AsyncSession
import os

from core.document import personal_document as document_service
from schemas.document.personal_document import (
    PersonalDocumentCreate, PersonalDocumentUpdate, PersonalDocumentResponse,
    PersonalDocumentDetailResponse, DocumentSearchRequest, PaginatedDocumentResponse,
    DocumentUploadResponse, BatchOperationRequest, BatchMoveRequest,
    DocumentStatistics, FileTypeInfo
)
from db.session import get_db
from log import log_api, log_error

router = APIRouter(
    prefix="/personal-documents",
    tags=["personal-documents"]
)


@router.get("/", response_model=PaginatedDocumentResponse)
async def get_documents(
    category_id: Optional[UUID] = Query(None, description="分类ID筛选"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    tags: Optional[List[str]] = Query(None, description="标签筛选"),
    is_favorite: Optional[bool] = Query(None, description="是否收藏筛选"),
    is_pinned: Optional[bool] = Query(None, description="是否置顶筛选"),
    sort_by: str = Query("created_at", description="排序字段"),
    sort_order: str = Query("desc", description="排序方向: asc/desc"),
    page: int = Query(1, description="页码", ge=1),
    size: int = Query(20, description="每页数量", ge=1, le=100),
    db: AsyncSession = Depends(get_db)
):
    """
    获取文档列表（支持分页、搜索、筛选、排序）
    
    - **category_id**: 按分类筛选
    - **search**: 在标题、描述、文件名中搜索
    - **tags**: 按标签筛选（可多选）
    - **is_favorite**: 筛选收藏文档
    - **is_pinned**: 筛选置顶文档
    - **sort_by**: 排序字段（created_at, title, file_size, view_count等）
    - **sort_order**: 排序方向（asc升序, desc降序）
    - **page**: 页码
    - **size**: 每页数量
    """
    log_api(f"获取文档列表: 页码{page}, 每页{size}条", module="router.personal_document")
    try:
        search_request = DocumentSearchRequest(
            category_id=category_id,
            search=search,
            tags=tags,
            is_favorite=is_favorite,
            is_pinned=is_pinned,
            sort_by=sort_by,
            sort_order=sort_order,
            page=page,
            size=size
        )
        return await document_service.search_documents(db, search_request)
    except Exception as e:
        log_error(f"获取文档列表失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取文档列表失败")


@router.post("/upload", response_model=DocumentUploadResponse)
async def upload_document(
    file: UploadFile = File(..., description="要上传的文件"),
    title: Optional[str] = Form(None, description="文档标题"),
    description: Optional[str] = Form(None, description="文档描述"),
    category_id: Optional[UUID] = Form(None, description="所属分类ID"),
    tags: Optional[str] = Form(None, description="标签列表，用逗号分隔"),
    db: AsyncSession = Depends(get_db)
):
    """
    上传文档
    
    - **file**: 要上传的文件（必填）
    - **title**: 文档标题（可选，为空时使用文件名）
    - **description**: 文档描述（可选）
    - **category_id**: 所属分类ID（可选）
    - **tags**: 标签列表，用逗号分隔（可选）
    
    支持的文件类型：PDF、Word、Excel、PowerPoint、文本文件、图片、压缩包等
    """
    log_api(f"上传文档: {file.filename}", module="router.personal_document")
    try:
        # 处理标签
        tag_list = []
        if tags:
            tag_list = [tag.strip() for tag in tags.split(',') if tag.strip()]
        
        # 创建文档数据
        document_data = PersonalDocumentCreate(
            title=title or file.filename,
            description=description,
            category_id=category_id,
            tags=tag_list
        )
        
        # 上传文档
        db_document = await document_service.upload_document(db, file, document_data)
        
        return DocumentUploadResponse(
            document=PersonalDocumentResponse.model_validate(db_document),
            message="文档上传成功"
        )
    except Exception as e:
        log_error(f"上传文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail=f"文档上传失败: {str(e)}")


@router.post("/batch-delete")
async def batch_delete_documents(
    request: BatchOperationRequest,
    db: AsyncSession = Depends(get_db)
):
    """
    批量删除文档
    
    - **document_ids**: 要删除的文档ID列表
    """
    log_api(f"批量删除文档: {len(request.document_ids)} 个", module="router.personal_document")
    try:
        deleted_count = await document_service.batch_delete_documents(db, request.document_ids)
        return {
            "message": f"成功删除 {deleted_count} 个文档",
            "deleted_count": deleted_count
        }
    except Exception as e:
        log_error(f"批量删除失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="批量删除失败")


@router.post("/batch-move")
async def batch_move_documents(
    request: BatchMoveRequest,
    db: AsyncSession = Depends(get_db)
):
    """
    批量移动文档到指定分类
    
    - **document_ids**: 要移动的文档ID列表
    - **category_id**: 目标分类ID（为空则移动到根目录）
    """
    log_api(f"批量移动文档: {len(request.document_ids)} 个到分类 {request.category_id}", module="router.personal_document")
    try:
        moved_count = await document_service.batch_move_documents(db, request.document_ids, request.category_id)
        return {
            "message": f"成功移动 {moved_count} 个文档",
            "moved_count": moved_count
        }
    except ValueError as e:
        log_error(f"批量移动参数错误: {str(e)}", module="router.personal_document")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        log_error(f"批量移动失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="批量移动失败")


@router.get("/{document_id}", response_model=PersonalDocumentDetailResponse)
async def get_document_detail(
    document_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    获取文档详情
    
    - **document_id**: 文档ID
    
    获取文档详细信息，包括关联的检查项，并更新访问记录
    """
    log_api(f"获取文档详情: {document_id}", module="router.personal_document")
    try:
        document = await document_service.get_document_detail(db, document_id)
        if not document:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        return PersonalDocumentDetailResponse.model_validate(document)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"获取文档详情失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取文档详情失败")


@router.put("/{document_id}", response_model=PersonalDocumentResponse)
async def update_document(
    document_id: UUID,
    document: PersonalDocumentUpdate,
    db: AsyncSession = Depends(get_db)
):
    """
    更新文档信息
    
    - **document_id**: 文档ID
    - 其他字段均为可选，只更新提供的字段
    """
    log_api(f"更新文档: {document_id}", module="router.personal_document")
    try:
        updated_document = await document_service.update_document(db, document_id, document)
        if not updated_document:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        return PersonalDocumentResponse.model_validate(updated_document)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"更新文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="更新文档失败")


@router.delete("/{document_id}")
async def delete_document(
    document_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    删除文档
    
    - **document_id**: 文档ID
    
    删除文档记录和对应的文件
    """
    log_api(f"删除文档: {document_id}", module="router.personal_document")
    try:
        success = await document_service.delete_document(db, document_id)
        if not success:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        return {"message": "文档删除成功"}
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"删除文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="删除文档失败")


@router.get("/{document_id}/download")
async def download_document(
    document_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    下载文档
    
    - **document_id**: 文档ID
    
    返回文档文件的二进制流
    """
    log_api(f"下载文档: {document_id}", module="router.personal_document")
    try:
        # 获取文档信息（这会更新访问记录）
        document = await document_service.get_document_detail(db, document_id)
        if not document:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        # 检查文件是否存在
        if not os.path.exists(document.file_path):
            log_error(f"文档文件不存在: {document.file_path}", module="router.personal_document")
            raise HTTPException(status_code=404, detail="文档文件不存在")
        
        return FileResponse(
            path=document.file_path,
            filename=document.filename,
            media_type=document.mime_type or 'application/octet-stream'
        )
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"下载文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="下载文档失败")


@router.post("/{document_id}/favorite", response_model=PersonalDocumentResponse)
async def toggle_favorite(
    document_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    切换文档收藏状态
    
    - **document_id**: 文档ID
    """
    log_api(f"切换文档收藏状态: {document_id}", module="router.personal_document")
    try:
        updated_document = await document_service.toggle_document_favorite(db, document_id)
        if not updated_document:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        return PersonalDocumentResponse.model_validate(updated_document)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"切换收藏状态失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="切换收藏状态失败")


@router.post("/{document_id}/pin", response_model=PersonalDocumentResponse)
async def toggle_pin(
    document_id: UUID,
    db: AsyncSession = Depends(get_db)
):
    """
    切换文档置顶状态
    
    - **document_id**: 文档ID
    """
    log_api(f"切换文档置顶状态: {document_id}", module="router.personal_document")
    try:
        updated_document = await document_service.toggle_document_pin(db, document_id)
        if not updated_document:
            raise HTTPException(status_code=404, detail="文档不存在")
        
        return PersonalDocumentResponse.model_validate(updated_document)
    except HTTPException:
        raise
    except Exception as e:
        log_error(f"切换置顶状态失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="切换置顶状态失败")


@router.get("/favorites/list", response_model=List[PersonalDocumentResponse])
async def get_favorite_documents(
    limit: int = Query(10, description="返回数量限制", ge=1, le=50),
    db: AsyncSession = Depends(get_db)
):
    """
    获取收藏的文档
    
    - **limit**: 返回结果数量限制
    """
    log_api(f"获取收藏文档，限制 {limit} 个", module="router.personal_document")
    try:
        documents = await document_service.get_favorite_documents(db, limit)
        return [PersonalDocumentResponse.model_validate(doc) for doc in documents]
    except Exception as e:
        log_error(f"获取收藏文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取收藏文档失败")


@router.get("/recent/list", response_model=List[PersonalDocumentResponse])
async def get_recent_documents(
    limit: int = Query(10, description="返回数量限制", ge=1, le=50),
    db: AsyncSession = Depends(get_db)
):
    """
    获取最近访问的文档
    
    - **limit**: 返回结果数量限制
    """
    log_api(f"获取最近访问文档，限制 {limit} 个", module="router.personal_document")
    try:
        documents = await document_service.get_recent_documents(db, limit)
        return [PersonalDocumentResponse.model_validate(doc) for doc in documents]
    except Exception as e:
        log_error(f"获取最近访问文档失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取最近访问文档失败")


@router.get("/statistics/overview", response_model=DocumentStatistics)
async def get_document_statistics(db: AsyncSession = Depends(get_db)):
    """
    获取文档统计信息
    
    返回：
    - 总文档数
    - 收藏文档数
    - 按文件类型统计
    - 按分类统计
    - 总文件大小
    """
    log_api("获取文档统计信息", module="router.personal_document")
    try:
        return await document_service.get_document_statistics(db)
    except Exception as e:
        log_error(f"获取文档统计失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取统计信息失败")


@router.get("/file-types/info", response_model=List[FileTypeInfo])
async def get_file_type_info():
    """
    获取支持的文件类型信息
    
    返回所有支持的文件类型及其图标、颜色等信息
    """
    log_api("获取文件类型信息", module="router.personal_document")
    try:
        from core.document.file_storage import FILE_TYPE_INFO
        
        file_types = []
        for ext, info in FILE_TYPE_INFO.items():
            if ext != 'default':
                file_types.append(FileTypeInfo(
                    extension=ext,
                    icon=info['icon'],
                    color=info['color'],
                    name=info['name']
                ))
        
        return file_types
    except Exception as e:
        log_error(f"获取文件类型信息失败: {str(e)}", exc_info=True, module="router.personal_document")
        raise HTTPException(status_code=500, detail="获取文件类型信息失败")
